package com.sinovatech.ologger.actionlog.aop;

import java.io.File;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import ognl.Ognl;

import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.ObjectUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.sinovatech.ologger.actionlog.core.LogHelper;
import com.sinovatech.ologger.actionlog.core.OperationLogInvocation;
import com.sinovatech.ologger.actionlog.core.OperationLogPersistence;
import com.sinovatech.ologger.actionlog.entity.OperationLog;
import com.sinovatech.ologger.util.LogUtil;
import com.sinovatech.ologger.util.StringHelper;

class AfterRunLog extends Thread implements Runnable {

	private static final Log logger = LogFactory.getLog(AfterRunLog.class);

	private OperationLogPersistence operationLogPersistence;

	private Method logMethod;
	private Object bean;
	private OperationLogInvocation invocationLog;
	private OperationLog log;
	private String operationDetails;
	private String conditionsJSON;
	private Object[] args;
	private String checkReturnExpression;

	public AfterRunLog(Method logMethod, Object bean, OperationLogInvocation invocationLog, OperationLog log, String operationDetails, String conditionsJSON,
			Object[] args, String checkReturnExpression) {
		super();
		init(logMethod, bean, invocationLog, log, operationDetails, conditionsJSON, args, checkReturnExpression);
	}

	public void init(Method logMethod, Object bean, OperationLogInvocation invocationLog, OperationLog log, String operationDetails, String conditionsJSON,
			Object[] args, String checkReturnExpression) {
		this.logMethod = logMethod;
		this.bean = bean;
		this.invocationLog = invocationLog;
		this.log = log;
		this.operationDetails = operationDetails;
		this.conditionsJSON = conditionsJSON;
		this.args = args;
		this.checkReturnExpression = checkReturnExpression;
	}

	public AfterRunLog() {

	}

	@SuppressWarnings("unchecked")
	public void run() {
		try {
			Integer result = null;
			if (logMethod != null) {
				result = (Integer) logMethod.invoke(bean, invocationLog);
			} else {
				Map ognlMap = new HashMap();
				ognlMap.put(LogHelper.VAR_RETURN, invocationLog.getReturnValue());
				ognlMap.put(LogHelper.VAR_ARGS, invocationLog.getArgs());
				List<String> cres = new ArrayList<String>();
				if (!StringHelper.isEmpty(checkReturnExpression)) {
					cres.add(checkReturnExpression);
				} else {
					cres.addAll(LogHelper.defaultSucessReturns);
				}
				for (String cre : cres) {
					Object parseExpression = Ognl.parseExpression(cre);
					try {
						Object value = Ognl.getValue(parseExpression, ognlMap);
						if (ObjectUtils.equals(value, true)) {
							result = 1;
							break;
						}
					} catch (Exception e) {
						logger.error(e.getMessage());
						logger.debug(LogUtil.stackTraceToString(e));
					}
				}
			}
			if (ObjectUtils.equals(result, OperationLogInvocation.RETURN_SUCCESS)) {
				log.flushOperationConditions();
				if (!StringHelper.isEmpty(log.getOperationDetails())) {
					operationDetails = log.getOperationDetails();
				}
				operationDetails = LogHelper.processOperationDetails(operationDetails, log.getOpcMap(), conditionsJSON);
				operationDetails = LogHelper.processOperationDetailsWithArgs(operationDetails, args);
				log.setOperationDetails(operationDetails);
				//处理操作名称
				String operationName = log.getOperationName();
				operationName = LogHelper.processOperationDetailsWithArgs(operationName, args);
				log.setOperationName(operationName);
				operationLogPersistence.saveOperationLog(log);
				logger.info(log.getOperationName());
				logger.info(log.getOperationConditions());
				logger.info(log.getOperationDetails());
				logger.info(log.getConditionsJSON());
			} else {
				if (!StringHelper.isEmpty(log.getOperationDetails())) {
					operationDetails = log.getOperationDetails();
					if (operationDetails.indexOf("[") > 0) {//有文件上传, 删除之
						try {
							String[] fileInfo = LogHelper.getUploadFileInfo(operationDetails);
							if (!(ArrayUtils.isEmpty(fileInfo) || fileInfo.length < 3)) {
								File file = new File(fileInfo[2]);
								if(file.exists()){
									file.delete();
									File parentFile = file.getParentFile();
									if (ArrayUtils.isEmpty(parentFile.listFiles())) {
										parentFile.delete();
									}
								}
							}
						} catch (Exception e) {
							logger.error("上传文件删除失败!");
							logger.error(LogUtil.stackTraceToString(e));
						}
					}
				}
			}
		} catch (Exception e) {
			logger.info(LogUtil.stackTraceToString(e));
		}
	}

	/**
	 * 需要注入日志处理的保存服务类
	 * @param operationLogPersistence
	 */
	public void setOperationLogPersistence(
			OperationLogPersistence operationLogPersistence) {
		this.operationLogPersistence = operationLogPersistence;
	}
}